import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Put,
  Query,
  Request,
  UseInterceptors,
  UploadedFile,
  ParseFilePipeBuilder,
  HttpStatus
} from '@nestjs/common'
import { Express } from 'express'
import {
  ApiBearerAuth,
  ApiOperation,
  ApiResponse,
  ApiTags
} from '@nestjs/swagger'
import { FileInterceptor } from '@nestjs/platform-express'

import { PostService } from './post.service'
import { IsPublic } from '../../common/decorator/is-public/is-public.decorator'

import {
  ResponseDto,
  BaseErrorDto,
  PostResponseDto,
  QueryDto,
  PostQueryPage,
  PostDto,
  PostSearchQueryPage,
  SetComment
} from './dtos/Response.dto'
import { PostEntity } from '../../entitys'
import { QueryPage } from '../apiProperty'

@ApiTags('商品相关')
@ApiBearerAuth()
@Controller('post')
export class PostController {
  constructor(private postService: PostService) {}

  @ApiResponse({ status: 200, type: PostResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '图片上传' })
  @Post('/upload')
  @UseInterceptors(FileInterceptor('file'))
  async upload(
    @UploadedFile(
      new ParseFilePipeBuilder()
        .addMaxSizeValidator({
          maxSize: 102400
        })
        .build({
          errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
        })
    )
    file: Express.Multer.File
  ) {
    return await this.postService.uploadFiles(file)
  }

  @ApiResponse({ status: 200, type: PostResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '新增商品 => 需要管理员身份' })
  @Post()
  async caretPost(
    @Body() body: PostDto,
    @Request() req: Record<string | symbol, Record<string, string>>
  ) {
    return await this.postService.caretPost(req.user.id, body)
  }

  @ApiResponse({ status: 200, type: PostResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '修改商品 => 需要管理员身份' })
  @Put()
  async updatePost(@Body() body: PostDto, @Query() query: QueryDto) {
    return await this.postService.updatePost(query.id, body)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '评论商品' })
  @Post('/:id/comment')
  async setComment(
    @Body() body: SetComment,
    @Param('id') id: string,
    @Request() req: Record<string | symbol, Record<string, string>>
  ) {
    return await this.postService.setComment(req.user.id, id, body)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '收藏商品' })
  @Get('/:id/star')
  async starPost(
    @Param('id') id: string,
    @Request() req: Record<string | symbol, Record<string, string>>
  ) {
    return await this.postService.starPost(req.user.id, id)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '点赞商品' })
  @Get('/:id/like')
  async likePost(
    @Param('id') id: string,
    @Request() req: Record<string | symbol, Record<string, string>>
  ) {
    return await this.postService.likePost(req.user.id, id)
  }
}

@ApiTags('商品相关')
@Controller('post')
export class PostControllerTow {
  constructor(private postService: PostService) {}

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '获取商品列表' })
  @IsPublic()
  @Get()
  async getPost(@Query() query: PostQueryPage) {
    return await this.postService.getPost(query)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '通过 ID 获取商品详情' })
  @IsPublic()
  @Get('/:id/get')
  async findPostById(
    @Param('id') id: string,
    @Request() req: Record<string | symbol, Record<string, string>>
  ) {
    return await this.postService.findPostById(id, req.user?.id || null)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '商品关键字搜索文章' })
  @IsPublic()
  @Get('/search')
  async findPostByKeyword(@Query() query: PostSearchQueryPage) {
    return await this.postService.findPostByKeyword(query)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '商品关键字搜索推荐' })
  @IsPublic()
  @Get('/search/recommend')
  async findPostRecommend(@Query() query: PostSearchQueryPage) {
    return await this.postService.findPostRecommend(query)
  }

  @ApiResponse({ status: 200, type: ResponseDto })
  @ApiResponse({ status: 400, type: BaseErrorDto })
  @ApiOperation({ summary: '获取商品评论列表' })
  @IsPublic()
  @Get('/:id/comment')
  async getComment(@Query() query: QueryPage, @Param('id') id: string) {
    return await this.postService.getComment(id, query)
  }
}
